/**
 *
 */
package com.googlecode.bip.chart;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import com.googlecode.bip.entity.impl.EntityHelper;

/**
 * @author Claude
 *
 */
public class DatePeriodImpl implements DatePeriod, Serializable
{
    private static final long serialVersionUID = 1L;
    private Calendar from;
    private Calendar to;
    private DatePeriodStep step;

    /**
     *
     */
    public DatePeriodImpl(
        final Date              fromDate,
        final Date              toDate,
        final DatePeriodStep    step
        )
    {
        this.from = new GregorianCalendar();
        this.from.setTime( fromDate );
        EntityHelper.getNormalizedCalendar( this.from );

        this.to = new GregorianCalendar();
        this.to.setTime( toDate );
        EntityHelper.getNormalizedCalendar( this.to );

        this.step   = step;
    }

    /**
    *
    */
   public DatePeriodImpl(
       final Calendar       from,
       final Calendar       to,
       final DatePeriodStep step
       )
   {
       this.from    = Calendar.class.cast( from.clone() );
       EntityHelper.getNormalizedCalendar( this.from );

       this.to      = Calendar.class.cast( to.clone() );;
       EntityHelper.getNormalizedCalendar( this.to );

       this.step    = step;
   }

    @Override // Iterable<Timestamp>
    public Iterator<Timestamp> iterator()
    {
//        final Calendar fromCalendar   = new GregorianCalendar();
//        final Calendar toCalendar     = new GregorianCalendar();
//
//        fromCalendar.setTime( EntityHelper.getNormalizedTimestamp( fromDate ) );
//        toCalendar.setTime( EntityHelper.getNormalizedTimestamp( toDate ) );
        return new Iterator<Timestamp>()
        {
            Calendar c = Calendar.class.cast( from.clone() );

            @Override
            public boolean hasNext()
            {
                return c.compareTo( to ) <= 0;
            }
            @Override
            public Timestamp next()
            {
                Timestamp ts = new Timestamp( c.getTimeInMillis() );

                c.add( Calendar.DAY_OF_MONTH, 1 );

                return ts;
            }
            @Override
            public void remove()
            {
                throw new UnsupportedOperationException();
            }
        };
    }

    @Override
    public Calendar getFrom()
    {
        return from;
    }

    @Override
    public Calendar getTo()
    {
        return to;
    }

    @Override
    public DatePeriodStep step()
    {
        return step;
    }

    public static DatePeriod getLastMonthDatePeriod()
    {
        final Calendar to   = new GregorianCalendar();
        final Calendar from = new GregorianCalendar();
        from.add( Calendar.MONTH, -1 );

        return new DatePeriodImpl( from, to, DatePeriodStepImpl.INC_DAY );
    }

    public static DatePeriod getLastYearDatePeriod()
    {
        final Calendar to   = new GregorianCalendar();
        final Calendar from = new GregorianCalendar();
        from.add( Calendar.YEAR, -1 );

        return new DatePeriodImpl( from, to, DatePeriodStepImpl.INC_DAY );
    }

}
